<template>
  <el-row>
    <el-row>
      <el-menu mode="horizontal" @select="handleSelect">
        <el-submenu index="1">
          <template slot="title">文件</template>
          <el-menu-item index="2-1">新建文件</el-menu-item>
          <el-menu-item index="2-2">新建窗口</el-menu-item>
          <el-menu-item index="2-3">打开文件...</el-menu-item>
          <el-menu-item index="2-3">打开目录...</el-menu-item>
          <el-menu-item index="2-3">保存...</el-menu-item>
          <el-menu-item index="2-3">另存为...</el-menu-item>
          <el-menu-item index="2-3">自动保存</el-menu-item>
          <el-submenu index="2-4">
            <template slot="title">选项</template>
            <el-menu-item index="2-4-1">开启自动保存</el-menu-item>
            <el-menu-item index="2-4-2">关闭自动保存</el-menu-item>
          </el-submenu>
        </el-submenu>
        <el-submenu index="2">
          <template slot="title">编辑</template>
          <el-menu-item index="2-1">撤销</el-menu-item>
          <el-menu-item index="2-2">重做</el-menu-item>
          <el-menu-item index="2-3">剪切</el-menu-item>
          <el-menu-item index="2-3">复制</el-menu-item>
          <el-menu-item index="2-3">粘贴</el-menu-item>
          <el-menu-item index="2-3">查找</el-menu-item>
          <el-menu-item index="2-3">替换</el-menu-item>
          <el-menu-item index="2-3">从文件中查找</el-menu-item>
          <el-menu-item index="2-3">从文件中替换</el-menu-item>          
        </el-submenu>
        <el-submenu index="3">
          <template slot="title">选择</template>
          <el-menu-item index="2-1">全选</el-menu-item>
          <el-menu-item index="2-2">复制选定内容</el-menu-item>       
        </el-submenu>
        <el-submenu index="4">
          <template slot="title">视图</template>
          <el-menu-item index="2-1">打开预览</el-menu-item>
          <el-menu-item index="2-2">打开调试</el-menu-item>       
        </el-submenu>
        <el-submenu index="5">
          <template slot="title">跳转</template>
          <el-menu-item index="2-1">返回</el-menu-item>
          <el-menu-item index="2-2">前进</el-menu-item>       
          <el-menu-item index="2-2">跳转到文件...</el-menu-item>       
        </el-submenu>
        <el-submenu index="6">
          <template slot="title">帮助</template>
          <el-menu-item index="2-1">关于</el-menu-item>
        </el-submenu>
      </el-menu>
    </el-row>
    <!-- 24 = 6 + 6 + 12 -->
    <el-col :span="6">
      <h6>预览窗口</h6>
      <iframe ref="previewWin" src="/preview.html" style="border: none; margin: 0; padding: 0; width: 350px; height: 667px; border: 1px solid #ccc;" border="no"></iframe>
    </el-col>
    <el-col :span="6">
      <h6>资源管理器</h6>
      <!--
      Attributes:
        current-node-key  当前选中的节点 string, number
        accordion 是否每次只打开一个同级树节点展开  boolean — false
        icon-class  自定义树节点的图标 string
        allow-drag  判断节点能否被拖拽 Function(node)  — —
        allow-drop  拖拽时判定目标节点能否被放置。type 参数有三种情况：'prev'、'inner' 和 'next'，分别表示放置在目标节点前、插入至目标节点和放置在目标节点后 Function(draggingNode, dropNode, type)  — —

      Props:
        isLeaf  指定节点是否为叶子节点，仅在指定了 lazy 属性的情况下生效 boolean, function(data, node) — —

      Events:
        node-contextmenu  当某一节点被鼠标右键点击时会触发该事件 共四个参数，依次为：event、传递给 data 属性的数组中该节点所对应的对象、节点对应的 Node、节点组件本身。
        check-change  节点选中状态发生变化时的回调  共三个参数，依次为：传递给 data 属性的数组中该节点所对应的对象、节点本身是否被选中、节点的子树中是否有被选中的节点
        current-change  当前选中节点变化时触发的事件  共两个参数，依次为：当前节点的数据，当前节点的 Node 对象

      Functions:
        getCurrentKey 获取当前被选中节点的 key，使用此方法必须设置 node-key 属性，若没有节点被选中则返回 null —
        getCurrentNode  获取当前被选中节点的 data，若没有节点被选中则返回 null
        setCurrentKey 通过 key 设置某个节点的当前选中状态，使用此方法必须设置 node-key 属性  (key) 待被选节点的 key，若为 null 则取消当前高亮的节点
        setCurrentNode  通过 node 设置某个节点的当前选中状态，使用此方法必须设置 node-key 属性 (node) 待被选节点的 node
        getNode 根据 data 或者 key 拿到 Tree 组件中的 node  (data) 要获得 node 的 key 或者 data
      -->
      <el-input
        placeholder="搜索文件"
        style="width: 100%;"
        v-model="filterText">
      </el-input>
      <el-tree
        :data="treeData"
        :props="treeDefaultProps"
        @node-click="treeHandleNodeClick"
        node-key="id"
        :current-node-key="100000"
        default-expand-all
        icon-class=""
        :filter-node-method="filterNode"
        ref="tree"
        :check-on-click-node="true"
        :highlight-current="true"
        :expand-on-click-node="false">        
        <span class="custom-tree-node" slot-scope="{ node, data }">
          <!-- <span>{{ node.label }}</span> -->
          <!-- 文件节点 -->
          <span v-if="node.isLeaf"><i class="vtl-icon vtl-menu-icon vtl-icon-file"></i> {{ node.label }}</span>
          <!-- 目录节点 -->
          <span v-else><i class="vtl-icon vtl-menu-icon vtl-icon-folder"></i> {{ node.label }}</span>

          <!-- 添加子目录 -->
          <span class="tip-menu" title="add folder" @click="() => treeAppend(data)"><i class="vtl-icon vtl-icon-folder-plus-e"></i></span>
          <!-- 添加子文件 -->
          <span class="tip-menu" title="add file" @click="() => treeAppend(data)"><i class="vtl-icon vtl-icon-plus"></i></span>
          <!-- 编辑 -->
          <span class="tip-menu" title="edit" ><i class="vtl-icon vtl-icon-edit"></i></span>
          <!-- 删除 -->
          <span class="tip-menu" title="delete" @click="() => treeRemove(node, data)"><i class="vtl-icon vtl-icon-trash"></i></span>          
        </span>
      </el-tree>
    </el-col>
    <el-col :span="12">
      <!-- <h6>编辑器</h6> -->
      <el-breadcrumb separator-class="el-icon-arrow-right" style="line-height: 30px;font-size: 12px;">
        <el-breadcrumb-item :to="{ path: '/' }">内容编辑区</el-breadcrumb-item>
        <el-breadcrumb-item v-for="(item, $index) in currentPathList" :key="$index">{{item}}</el-breadcrumb-item>
      </el-breadcrumb>
      <textarea ref="jsonSource" v-model="editorContent"></textarea>
      <div id="terminal" ref="terminal"></div>
    </el-col>
  </el-row>
</template>
<style scoped>
h6{
  color: #333;
  margin: 0;
  line-height: 30px;
}
</style>
<script>
  import 'codemirror/lib/codemirror.css'
  // import 'codemirror/theme/base16-dark.css'
  import 'codemirror/addon/fold/foldgutter.css'

  import CodeMirror from 'codemirror/lib/codemirror'
  import 'codemirror/mode/htmlmixed/htmlmixed'
  import 'codemirror/mode/javascript/javascript'
  import 'codemirror/addon/selection/active-line'

  import 'codemirror/addon/fold/foldcode'
  import 'codemirror/addon/fold/foldgutter'
  import 'codemirror/addon/fold/brace-fold'
  import 'codemirror/addon/fold/comment-fold'

  import Terminal from '~/assets/js/terminal'

  let treeNodeId = 9999;
  async function treePath(fullPath, treeList, index) {
    var fileList = await fs.readdir(fullPath);
    fileList.forEach(async (file, fIndex) => {
      if (file.isDirectory) {
        treeList.push({
            id: index + fIndex,
            label: file.name,
            fullPath: file.fullPath,
            children: await treePath(file.fullPath, [], (index + fIndex) * 10)
        })
      } else {
        treeList.push({
            id: index + fIndex,
            label: file.name,
            fullPath: file.fullPath,
            isLeaf: true
        })
      }
    })
    return treeList;
}
  export default {
    components: {},
    watch: {
      filterText(val) {
        this.$refs.tree.filter(val);
      }
    },
    data() {
      return {
        currentFullPath: '/src/widget/platform/introduce-ol/render/index.vue',
        currentPathList: 'src/widget/platform/introduce-ol/render/index.vue'.split('/'),
        filterText: '',
        treeData: [],
        treeDefaultProps: {
          children: 'children',
          label: 'label'
        },
        // editorContent: `${JSON.stringify({
        //   name: 'jm'
        // })}`,
        editorContent: `<template>
<div>
  <div>Hello, {{uname}}!!!</div>
  <div class="demo">this is text...</div>
</div>
</template>
<style scoped>
.demo{
  color: red;
  border: 1px solid #ccc;
  background: #f3f3f3;
  width: 100%;
}
</style>
<script>
export default {
  data () {
    return {
      uname: 'jm'
    }
  }
}
<\/script>
        `
      }
    },
    mounted () {
      let vm = this;
      window.vm = this;
      this.initFS();
      this.codeMirrorEditor = CodeMirror.fromTextArea(this.$refs.jsonSource, {
        tabSize: 4,
        styleActiveLine: true,
        lineNumbers: true,
        line: true,
        mode: 'text/html',
        // mode: 'text/javascript',
        // theme: 'base16-dark',
        // 折叠配置
        foldGutter: true,
        lineWrapping: true,
        gutters: [
          'CodeMirror-linenumbers',
          'CodeMirror-foldgutter',
          'CodeMirror-lint-markers'
        ]
      });
      // init refresh
      vm.$refs.previewWin.onload = () => {
        vm.$refs.previewWin.contentWindow.postMessage({
          method: 'refresh',
          payload: {
            content: vm.editorContent
          }
        }, '*');
      };
      // watch change refresh
      this.codeMirrorEditor.on("change", function(context) {
        // only vue file be changed then refresh page
        if (/\.vue$/.test(vm.currentFullPath)) {
          vm.$refs.previewWin.contentWindow.postMessage({
            method: 'refresh',
            payload: {
              content: vm.codeMirrorEditor.getValue()
            }
          }, '*');
        }
      });
      // 控制台初始化
      var t1 = new Terminal('terminal')
      t1.setHeight("200px")
      t1.setWidth('100%')
      t1.setTextSize('12px')
      t1.blinkingCursor(true)
      this.$refs.terminal.appendChild(t1.html)
      // document.body.appendChild(t1.html)
      t1.print('控制台')
      t1.input('> 请输入命令:', function (input) {
        t1.print('> Welcome, ' + input)

        // t2.sleep(1000, function () {
        //   t2.print('Hello again!')
        //   t2.input('Whats your name again?', function (input) {
        //     t2.print('Welcome again, ' + input)
        //   })
        // })
      })
    },
    methods: {
      async initFS () {
        // 5M
        await fs.init({type: window.TEMPORARY, bytes: 5 * 1024 * 1024});
        let isExists = await fs.exists('/README.md');
        if (!isExists) {
          await fs.mkdir('src');
          await fs.mkdir('src/widget');
          await fs.mkdir('src/widget/platform');
          await fs.mkdir('src/widget/platform/introduce-ol');
          await fs.mkdir('src/widget/platform/introduce-ol/render');
          await fs.mkdir('src/widget/platform/introduce-ol/editor');
          // await fs.mkdir('src/widget/platform/introduce-ol/images');
          await fs.writeFile('/README.md', '这是帮助文档');
          await fs.writeFile('/package.json', JSON.stringify({
            name: 'project-demo',
            version: '1.0.0'
          }, null, 2));
          await fs.writeFile('src/widget/platform/introduce-ol/render/index.vue', this.editorContent);
          await fs.writeFile('src/widget/platform/introduce-ol/editor/main.js', `
export default {
  init: function(){},
  install: function(){},
  uninstall: function(){}
}
          `);
        }
        
        const content = await fs.readFile('/README.md');
        console.log(content); // => "hello world"
        this.treeData = await treePath('/', [], 1);
      },
      handleSelect () {},
      filterNode(value, data) {
        if (!value) return true;
        return data.label.indexOf(value) !== -1;
      },
      async treeHandleNodeClick(data) {
        if (data.isLeaf) {
          this.currentFullPath = data.fullPath;
          this.currentPathList = data.fullPath.replace(/^\//, '').split('/');
          this.editorContent = await fs.readFile(data.fullPath);
          this.codeMirrorEditor.setValue(this.editorContent);
          if (/\.(js|json)$/.test(data.fullPath)) {
            vm.codeMirrorEditor.setOption('mode', 'text/javascript');
          } else if (/\.(vue|html?)$/.test(data.fullPath)){
            vm.codeMirrorEditor.setOption('mode', 'text/html');
          }
        }
      },
      treeAppend(data) {
        const newChild = { id: treeNodeId++, label: 'testtest', children: [] };
        if (!data.children) {
          this.$set(data, 'children', []);
        }
        data.children.push(newChild);
      },
      treeRemove(node, data) {
        const parent = node.parent;
        const children = parent.data.children || parent.data;
        const index = children.findIndex(d => d.id === data.id);
        children.splice(index, 1);
      },
      getNewTree() {
        var vm = this
        function _dfs(oldNode) {
          var newNode = {}
 
          for (var k in oldNode) {
            if (k !== 'children' && k !== 'parent') {
              newNode[k] = oldNode[k]
            }
          }
 
          if (oldNode.children && oldNode.children.length > 0) {
            newNode.children = []
            for (var i = 0, len = oldNode.children.length; i < len; i++) {
              newNode.children.push(_dfs(oldNode.children[i]))
            }
          }
          return newNode
        }
 
        vm.newTree = _dfs(vm.data)
      }
    }
  }
</script>